#include "comm.h"

void sig_handler(int signo)
{
	if (signo == SIGINT)
	{
        global().still_alive = false;
	}
}

void echo_handler(std::pair<u64, strref> &&msg)
{
    const string tmp = "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ntest";
    global().listener.send(msg.first, strdup(tmp.c_str()), tmp.length());
    global().listener.close(msg.first);
};

int main(int argc, char *argv[])
{
    raise(SIGTRAP);
    signal(SIGINT, sig_handler);

    //load global config
    if (global().proper.load("/usr/local/etc/global.conf") &&
        global().proper.load("/usr/local/etc/echoer.conf"))
    {
        global().logger.log_fatal(PROJECT, "fail to load cfg file");
        return 1;
    }

    global().logger.log_notice(PROJECT, "application is starting up...");

    //init logger
    string log_file = global().proper.get("echoer.logger.file", "/usr/local/var/log/echoer.log");

    if (global().logger.open(log_file, 7, true))
    {
        global().logger.log_fatal(PROJECT, "fail to open log file: %s", log_file.c_str());
        return 2;
    }

    //other modules
    mod::Listener::Config tcpsvr_conf;
    tcpsvr_conf.local_af = AF_INET;
    tcpsvr_conf.local_addr = global().proper.get("echoer.network.host", "0.0.0.0");
    tcpsvr_conf.local_port = global().proper.get("echoer.network.port", int(8000));
    tcpsvr_conf.accepted = [](u64 cid, const char *addr, int port) { return; };
    tcpsvr_conf.received = [](u64 cid, const char *addr, int port, strref &&str) { global().echo_handler.deliver(std::make_pair(std::move(cid), std::move(str))); };
    tcpsvr_conf.closed = [](u64 cid) { return; };

    if (global().listener.start(tcpsvr_conf))
    {
        global().logger.log_error(PROJECT, "fail to start tcp server");
        return 4;
    }

    if (global().echo_handler.start(echo_handler))
    {
        global().logger.log_error(PROJECT, "fail to start echo handler");
        return 5;
    }

    //into main loop
	global().still_alive = true;

    while (global().still_alive)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    global().logger.log_notice(PROJECT, "application is shutting down...");
    global().echo_handler.stop();
    global().listener.stop();

    global().logger.log_notice(PROJECT, "bye.");
	return 0;
}

